--[[
Name: WhoFavorites-2.0
Revision: $Rev: 200 $
Author(s): Driizt@BB - WotLK, Bolagio (bolagio@gmail.com)
Inspired By: Who Favorites by Rizzle of Twisting Nether(Horde) and AHFavorites by Narwick
Website: 
Documentation: 
SVN: http://svn.wowace.com/wowace/trunk/WhoFavorites/
Description: WhoFavorites saves Who queries in a simple drop-down list for easy access.
License: GPL v2 or later
Dependencies: (optional) Ace2
]]

local L = AceLibrary("AceLocale-2.2"):new("WhoFav")

-- Chat commands
local opts = { 
    type='group',
    name = L["Who Favorites"],
    args = {
        autoQuery = {
            type = 'toggle',
            name = L["AutoQuery"],
            desc = L["Automatically run a favorite who search when selected from the list."],
            get = "IsAutoQuery",
            set = "ToggleAutoQuery",
        },
    },
}

WhoFav = AceLibrary("AceAddon-2.0"):new("AceConsole-2.0", "AceEvent-2.0", "AceDB-2.0")
WhoFav:RegisterChatCommand(L["Slash-Commands"], opts)

WhoFav:RegisterDB("WhoFavDB", "WhoFavDBPerChar")
WhoFav:RegisterDefaults("profile", {
    searches = {},
})
WhoFav:RegisterDefaults("char", {
    autoQuery = true,
})

function WhoFav:OnInitialize()
    -- register to be notified when who interface comes up
	self:RegisterEvent("FRIENDLIST_SHOW", "Position")
	-- setup search accessor/setter
	self.GetSearch = function(key)
		return self.db.profile.searches[key]
	end
	self.SetSearch = function(key, val)
        self.db.profile.searches[key] = val
    end
	self.AllSearches = function() 
        local v = self.db.profile.searches
        if (v == nil) then
            return {}
        end
        return v
	end	
	self:Print(L["Enabled"])
end

function WhoFav:OnEnable()  
	WhoFavFrame:Show();
end

function WhoFav:OnDisable()
	WhoFavFrame:Hide();
end

function WhoFav:IsAutoQuery()
    return self.db.char.autoQuery
end

function WhoFav:ToggleAutoQuery()
    self.db.char.autoQuery = not self.db.char.autoQuery
end
	
-- Save the current search criteria
function WhoFav:SaveSearch(searchName)    
	local searchValue = WhoFrameEditBox:GetText()

  if (searchName == nil or searchName == "") then
      self:Print(L["New Search Name cannot be blank."])
      return
  end

  self:Print(string.format(L["Added who search %q to favorites."], searchName))
    
	-- now save them
	self.SetSearch(searchName, searchValue);
	
	-- reinitialize the popup to set the new value in the proper place
	UIDropDownMenu_Initialize(WhoFavFrame, WhoFavSearchesDropDown_Initialize);

	-- set the popup list to the newly saved entry
	
	-- This is the way to do it looking at the API, but when
	-- a pseudo dropdown is being used, an internal call
	-- to SetText in UIDropDown.lua fails because there
	-- is no currently selected label.
--		UIDropDownMenu_SetSelectedName(WhoFavFrame, searchName);

	-- Instead, set the internal vars directly.  This may blow up at
	-- some point in the future, but oh well.
	WhoFavFrame.selectedName = searchName;
	WhoFavFrame.selectedID = nil;
	WhoFavFrame.selectedValue = nil;

	-- run it
	if (self:IsAutoQuery()) then
  	WhoFrameEditBox_OnEnterPressed(WhoFrameEditBox);
		WhoFrame.selectedWho = nil;
  end
end

function WhoFav:RunSearch(searchName, clear)
	-- initialize for a blank search
	local searchValue = ""
	
	-- Get the selected search		
	if (not clear) then 
		searchValue = self.GetSearch(searchName);
	end
    
    if (searchValue == nil) then
        self:Print(string.format(L["Favorite who search %q is blank."], searchName))
        return
    end
			
	-- Load the fields
	WhoFrameEditBox:SetText(searchValue);
	
	-- Update the popup to the current search, or clear it
	if (not clear) then
		-- See notes in SaveSearch
--			UIDropDownMenu_SetSelectedName(WhoFavFrame, searchName);
		WhoFavFrame.selectedName = searchName;
		WhoFavFrame.selectedID = nil;
		WhoFavFrame.selectedValue = nil;
	else
		-- See notes in SaveSearch
--			UIDropDownMenu_ClearAll(WhoFavFrame);
		WhoFavFrame.selectedName = nil;
		WhoFavFrame.selectedID = nil;
		WhoFavFrame.selectedValue = nil;
	end
	
	-- run it
	if (self:IsAutoQuery()) then
		WhoFrameEditBox_OnEnterPressed(WhoFrameEditBox);
		WhoFrame.selectedWho = nil;
  end
end

function WhoFav:DeleteSearch(searchName)
	-- check if nothing is selected, return if so
	if (searchName == nil) then
		return
	end
	
	-- Remove the search
	self.SetSearch(searchName, nil);
    self:Print(string.format(L["Favorite who search %q deleted."], searchName))
	
	-- Clear the previously selected search
	-- See notes in SaveSearch
--		UIDropDownMenu_ClearAll(WhoFavFrame);
	WhoFavFrame.selectedName = nil;
	WhoFavFrame.selectedID = nil;
	WhoFavFrame.selectedValue = nil;
end

-- GUI Functions

function WhoFav:SearchesDropDown_OnLoad(self)
	UIDropDownMenu_Initialize(self:GetParent(), WhoFavSearchesDropDown_Initialize);
	UIDropDownMenu_SetAnchor(self, -124, 0, self:GetParent(), "TOPLEFT", self:GetName(), "BOTTOMRIGHT")
end

function WhoFavSearchesDropDown_Initialize()

	-- Skip everything if WhoFav object hasn't loaded yet
	if (not WhoFav) then
		return
	end
	
	local info = {};
	local searches = {};

	-- Add a title item
	local favoritesTitle = {};
	favoritesTitle.text = L["Who use: z-<zone> c-<class> g-<guild>"];
	favoritesTitle.notClickable = true;
	favoritesTitle.notCheckable = true;		
	UIDropDownMenu_AddButton(favoritesTitle);

	-- Add a "hint"
	local favoritesHint = {};
	favoritesHint.text = L["Example: c-warrior 61-70"];
	favoritesHint.notClickable = true;
	favoritesHint.notCheckable = true;		
	UIDropDownMenu_AddButton(favoritesHint);
    
	-- Separator
	local separator = {};
	separator.text = L["-------------------------------------"];
	separator.notClickable = true;
	separator.notCheckable = true;
	UIDropDownMenu_AddButton(separator);
	
	-- Add all the saved searches
	if (WhoFav.AllSearches) then
		searches = WhoFav:AllSearches();
	end
    
    local favoritesLabel = {};
    favoritesLabel.text = L["Favorites:"];
    favoritesLabel.notClickable = true;
    favoritesLabel.notCheckable = true;		
    UIDropDownMenu_AddButton(favoritesLabel);

	for i,v in pairsByKeys(searches) do
		info.text = i;
		local staticText = i;
		info.func = function () WhoFav:RunSearch(staticText); end;
		info.checked = false;
		UIDropDownMenu_AddButton(info);
	end
	
	-- Separator
	UIDropDownMenu_AddButton(separator);
	
	-- Save Button
	info.text = L["Save"];
	info.func = function () StaticPopup_Show("WHOF_SAVESEARCH"); end;
	info.notCheckable = true;
	info.checked = false;

	UIDropDownMenu_AddButton(info);
	
	-- Delete Button
	info.text = L["Delete"];
	info.func = function ()
		currentSearch = UIDropDownMenu_GetSelectedName(WhoFavFrame);
		WhoFav:DeleteSearch(currentSearch); 
	end;
	info.notCheckable = true;
	info.checked = false;
	
	UIDropDownMenu_AddButton(info);

	-- Clear Button
	info.text = L["Clear"];
	info.func = function ()
		WhoFav:RunSearch(nil, true); 
	end;
	info.notCheckable = true;
	info.checked = false;	
	UIDropDownMenu_AddButton(info);

end

-- repositions WhoFav dropdown with dynamic loaded friends interface
function WhoFav:Position()
	WhoFavFrame:ClearAllPoints()
	WhoFavFrame:SetParent("WhoFrameEditBox")
	WhoFavFrame:SetFrameStrata("HIGH")
	WhoFavFrame:SetPoint("TOPLEFT", "WhoFrameEditBox", "TOPLEFT", 195, -45)
	WhoFavFrameButton:Show()
	WhoFavFrame:Show()
end

-- save popup
StaticPopupDialogs["WHOF_SAVESEARCH"] = {
	text = L["New Search Name"],
	button1 = L["Save"],
	button2 = L["Cancel"],
	hasEditBox = 1,
	maxLetters = 40,
	OnAccept = function(self)
		local editBox = getglobal(self:GetName().."EditBox");
		WhoFav:SaveSearch(editBox:GetText());
		self:Hide();
	end,
	OnShow = function(self)
		getglobal(self:GetName().."EditBox"):SetFocus();
		getglobal(self:GetName().."EditBox"):SetText(WhoFrameEditBox:GetText());
	end,
	OnHide = function(self)
		if ( ChatFrameEditBox:IsVisible() ) then
			ChatFrameEditBox:SetFocus();
		end
		getglobal(self:GetName().."EditBox"):SetText("");
	end,
	EditBoxOnEnterPressed = function(self)
		local editBox = getglobal(self:GetParent():GetName().."EditBox");
		WhoFav:SaveSearch(editBox:GetText());
		self:GetParent():Hide();
	end,
	EditBoxOnEscapePressed = function(self)
		self:GetParent():Hide();
	end,
	timeout = 0,
	exclusive = 1,
	whileDead = 1
};

-- Utility function to sort searches
-- Lifted from LUA book online
function pairsByKeys (t, f)
	local a = {}
	for n in pairs(t) do table.insert(a, n) end
	table.sort(a, f)
	local i = 0      -- iterator variable
	local iter = function ()   -- iterator function
		i = i + 1
		if a[i] == nil then return nil
		else return a[i], t[a[i]]
		end
	end
	return iter
end
